Skip to main content

Vectors

A vector is a growable, heap-allocated array that stores values of the same type in contiguous memory.

Think of Vec<T> as: “An array that can grow and shrink safely.”

let v = vec![1, 2, 3];
  • Stores elements of type i32
  • Allocated on the heap
  • Size can change at runtime

Explicit Type

let v: Vec<i32> = Vec::new();

Vec<T> is generic — it works with any type.

Key Characteristics of Vec<T>

FeatureVector
SizeDynamic
MemoryHeap
Grow/Shrink✅ Yes
IndexingO(1)
OwnershipOwns elements
SafetyBounds-checked

Creating Vectors

  • Empty Vector: let mut v: Vec<i32> = Vec::new();
  • Using vec! Macro: let v = vec![10, 20, 30];
  • Initialize with Repeated Values: let v = vec![0; 5]; Creates: [0, 0, 0, 0, 0]

Adding Elements

Using push()

let mut v = Vec::new();

v.push(1);
v.push(2);
v.push(3);

Vector grows automatically.

Capacity vs Length

let mut v = Vec::with_capacity(5);

v.push(1);
v.push(2);

println!("Length: {}", v.len());
println!("Capacity: {}", v.capacity());
  • len() → number of elements
  • capacity() → allocated space

Accessing Elements

Using Index (Risky)

let v = vec![10, 20, 30];
println!("{}", v[1]); // 20

Panic if index is out of bounds.

Safe Access Using .get()

let v = vec![10, 20, 30];

match v.get(5) {
Some(value) => println!("{}", value),
None => println!("Index out of bounds"),
}

Iterating Over Vectors

Immutable Iteration

let v = vec![1, 2, 3];

for x in &v {
println!("{}", x);
}

Mutable Iteration

let mut v = vec![1, 2, 3];

for x in &mut v {
*x *= 2;
}

Vector becomes: [2, 4, 6]

Consuming Iteration

let v = vec![1, 2, 3];

for x in v {
println!("{}", x);
}

v is moved and can’t be used after.

Removing Elements

Remove Last Element

let mut v = vec![1, 2, 3];
let last = v.pop();

last is Option<i32>

Remove by Index

let mut v = vec![10, 20, 30];
v.remove(1);

Vector becomes: [10, 30]

Slicing Vectors (&[T])

Create a Slice

let v = vec![1, 2, 3, 4, 5];
let slice = &v[1..4];

Type: &[i32]

Why Slices Matter

  • No ownership transfer
  • Works for arrays and vectors
  • Ideal for function parameters
fn print_slice(slice: &[i32]) {
for x in slice {
println!("{}", x);
}
}

Vectors and Ownership

Moving a Vector

let v1 = vec![1, 2, 3];
let v2 = v1; // ownership moved

v1 is no longer valid.

Borrowing a Vector

let v = vec![1, 2, 3];
print_vec(&v);

fn print_vec(v: &Vec<i32>) {
println!("{:?}", v);
}

Better:

fn print_vec(v: &[i32]) {
println!("{:?}", v);
}

Storing Different Types (Using Enums)

Vectors can store only one type, but enums help.

enum Value {
Int(i32),
Float(f64),
Text(String),
}

let v = vec![
Value::Int(10),
Value::Float(3.14),
Value::Text(String::from("Rust")),
];

Common Vector Methods

MethodPurpose
push()Add element
pop()Remove last
len()Number of elements
capacity()Allocated space
clear()Remove all
contains()Check value
sort()Sort elements

Arrays vs Vectors (Quick Recap)

FeatureArrayVector
SizeFixedDynamic
MemoryStackHeap
Resize
Use caseKnown sizeRuntime data